<?php

class Application_Model_UserPerms
{
    protected $_acl;
    protected $_roles;
    protected $_default_role_id;
    protected $_admin_role_id;
    protected $_resources;
    
    const VIEW_PERM='view';
    const POST_PERM='post';
    const MANAGE_PERM='manage';

    /**
     * Constructor
     *
     * @param object $role
     * @param object $resource
     */
    public function __construct()
    {
        $this->_acl=new Zend_Acl();
        
        $this->_initRoles(Application_Model_UserRoles::getValidRoles(),Application_Model_UserRoles::getDefaultRole());
        
        $this->_default_role_id=Application_Model_UserRoles::getDefaultRole();
        $this->_admin_role_id=Application_Model_UserRoles::getAdminRole();
        
        $this->_initResources(Application_Model_UserResources::getValidResources());
        
        $this->_initPerms();
    }
    
    /**
     * Initializing ACL roles
     *
     * @param array $roles
     * @param string $default
     */
    protected function _initRoles($roles,$default)
    {
        if (empty($roles) || !is_array($roles) || empty($default)) return;
        
        $this->_roles=array();
        
        $this->_acl->addRole($default);
        $this->_roles[]=$default;
        
        foreach ($roles as $role)
        {
            if ($role==$default) continue;
            
            $this->_acl->addRole($role,$default);
            $this->_roles[]=$role;
        }
    }
    
    /**
     * Initializing ACL resources
     *
     * @param array $resources
     */
    protected function _initResources($resources)
    {
        if (empty($resources) || !is_array($resources)) return ;
        
        $this->_resources=array();
        
        foreach ($resources as $resource) 
        {
            $this->addResource($resource);
        }
    }
    
    /**
     * Adds ACL resource
     * 
     * @param string $resource
     */
     
    public function addResource($resource)
    {
        $this->_acl->addResource($resource);
        $this->_resources[]=$resource;
    }
    
    /**
     * Initializing default permissions
     *
     */
    protected function _initPerms()
    {
        foreach ($this->_resources as $resource)
        {
            $this->_setResourceDefaultPerms($resource);
        }
    }
    
    /**
     * Sets role default permissions for resource
     *
     * @param string $resource
     */
    protected function _setResourceDefaultPerms($resource)
    {
        $this->_acl->allow($this->_admin_role_id,$resource,self::VIEW_PERM);
        $this->_acl->allow($this->_admin_role_id,$resource,self::POST_PERM);
        $this->_acl->allow($this->_admin_role_id,$resource,self::MANAGE_PERM);
    }
    
    /**
     * Checks if role has given permission for resource
     *
     * @param object $role
     * @param object $resource
     * @param ustring $permission
     * @return bool
     */
    protected function _isAllowed(Application_Model_UserRoles $role,Application_Model_UserResources $resource,$permission)
    {
        return $this->_acl->isAllowed($role,$resource,$permission);
    }
    
    /**
     * Checks role view permission for resource
     *
     * @param object $role
     * @param object $resource
     * @return bool
     */
    public function canView(Application_Model_UserRoles $role,Application_Model_UserResources $resource)
    {
        return $this->_isAllowed($role,$resource,self::VIEW_PERM);
    }
    
    /**
     * Checks role post permission for resource
     *
     * @param object $role
     * @param object $resource
     * @return bool
     */
    public function canPost(Application_Model_UserRoles $role,Application_Model_UserResources $resource)
    {
        return $this->_isAllowed($role,$resource,self::POST_PERM);
    }
    
    /**
     * Checks role manage permission for resource
     *
     * @param object $role
     * @param object $resource
     * @return bool
     */
    public function canManage(Application_Model_UserRoles $role,Application_Model_UserResources $resource)
    {
        return $this->_isAllowed($role,$resource,self::MANAGE_PERM);
    }
    
    /**
     * Sets access permission
     *
     * @param string $role
     * @param string $resource
     * @param string $permission
     */
    public function allow($role,$resource,$permission)
    {
        $this->_acl->allow($role,$resource,$permission);
    }
}

